# -*- coding: utf-8 -*- 
"""
========================================================================================================================
@project : my-sanic
@file: myMongo
@Author: mengying
@email: 652044581@qq.com
@date: 2023/3/16 21:31
@desc: mongodb的连接池，同步和异步的连接池对象
========================================================================================================================
"""
from motor.motor_asyncio import AsyncIOMotorClient
from threading import Lock
import pymongo
from urllib import parse


class SingletonMeta(type):
    """元类单例"""
    __instance = None
    __lock = Lock()

    def __call__(cls, *args, **kwargs):
        with cls.__lock:
            new = kwargs.pop('new', None)
            if new is True:
                return super().__call__(*args, **kwargs)
            if not cls.__instance:
                cls.__instance = super().__call__(*args, **kwargs)
        return cls.__instance


class MongoConfig(metaclass=SingletonMeta):
    """mongodb的配置配置项（单例配置），做字符串的转换"""

    def __init__(self, host=None, port=None, username=None, password=None, db=None):
        self._host = host
        self._port = port
        self._username = parse.quote_plus(username)
        self._password = parse.quote_plus(password)
        self.db = db
        self.url = 'mongodb://%s:%s@%s:%s' % (self._username, self._password, self._host, self._port)


class AsyncMongoClient(object):
    """异步的mongo连接对象"""
    _instance = None

    def __new__(cls):
        if AsyncMongoClient._instance is None:
            AsyncMongoClient._instance = object.__new__(cls)

            AsyncMongoClient._instance.client = AsyncIOMotorClient(MongoConfig().url)

            AsyncMongoClient._instance.db = AsyncMongoClient._instance.client[MongoConfig().db]

        return AsyncMongoClient._instance.db


class SyncMongoClient(object):
    """同步的mongo连接对象"""
    _instance = None

    def __new__(cls):
        if SyncMongoClient._instance is None:
            SyncMongoClient._instance = object.__new__(cls)

            SyncMongoClient._instance.client = pymongo.MongoClient(MongoConfig().url)

            SyncMongoClient._instance.db = SyncMongoClient._instance.client[MongoConfig().db]

        return SyncMongoClient._instance.db
